<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Http\Filters\ReportsFilter;
use App\Http\Requests\Centers\CentersUpdateRequest;
use App\Http\Requests\Reports\FilterRequest;
use App\Http\Requests\Reports\ReportsStoreRequest;
use App\Http\Requests\Reports\ReportsUpdateRequest;
use App\Http\StaticData;
use App\Http\Traits\CurrentCenters;
use App\Models\Centers;
use App\Models\Instructors;
use App\Models\Members;
use App\Models\Reports;
use App\Models\Sickness;
use App\Models\User;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Rap2hpoutre\FastExcel\FastExcel;


class ReportsController extends Controller
{
    use StaticData;

    public function show(FilterRequest $request)
    {
        $currentCenters = [];

        foreach (User::find(Auth::id())->centers as $center) {
            $currentCenters[] = $center->id;
        }

        $data = $request->validated();


        if (!in_array(3, $currentCenters)) {
            $instructors = Instructors::query();
            $instructors->whereIn('centers_id', $currentCenters);
            $instructors = $instructors->get();
        } else {
            $instructors = Instructors::all();
        }

        if (!in_array(3, $currentCenters)) {
            $centers = Centers::where('user_id', Auth::id())->get();
        } else {
            $centers = Centers::all();
        }


        if (isset($data['filters'])) {


            if (!isset($data['filters']['centers_id'])) {
                $data['filters']['centers_id'] = $centers->pluck('id')->toArray();
            }


            $filter = app()->make(ReportsFilter::class, ['queryParams' => array_filter($data['filters'])]);


            if (isset($data['filters']['diagnosis'])) {
                $diagnosisFilter = $data['filters']['diagnosis'];
                $tempReports = Reports::filter($filter);
                $reports = $tempReports->whereHas('member', function ($tempReports) use ($diagnosisFilter) {
                    $count = 0;
                    foreach ($diagnosisFilter as $val) {
                        if ($count > 0) {
                            $tempReports->orWhere('diagnosis', trim($val));
                        } else {
                            $tempReports->where('diagnosis', trim($val));
                        }
                        $count++;
                    }

                })->paginate(30);
                $statistics = $this->statistics($filter);
            } else {
                $reports = Reports::filter($filter)->paginate(30);
                $statistics = $this->statistics($filter);
            }

            unset($data['filters']['diagnosis']);

        } else {
            if (!in_array(3, $currentCenters)) {

                if (!isset($data['filters']['centers_id'])) {
                    $filterCenter['centers_id'] = $centers->pluck('id')->toArray();
                }

                $filter = app()->make(ReportsFilter::class, ['queryParams' => array_filter($filterCenter)]);
                $reports = Reports::filter($filter)->paginate(30);
                $statistics = $this->statistics($filter);
            } else {
                $reports = Reports::paginate(30);
                $statistics = $this->statistics();
            }


        }


        if (!in_array(3, $currentCenters)) {
            $yearsQuery = Reports::query();
            $yearsQuery->whereIn('centers_id', $currentCenters);
            $years = $yearsQuery->get()->unique('year');
        } else {
            $years = Reports::select('year')->distinct()->get();
        }

        if (!in_array(3, $currentCenters)) {
            $lessonsQuery = Reports::query();
            $lessonsQuery->whereIn('centers_id', $currentCenters);
            $lessons = $lessonsQuery->get()->unique('lessons');
        } else {
            $lessons = Reports::select('lessons')->distinct()->get();
        }


        $months = $this->months;
        $programs = $this->programs;
        $sickness = Sickness::all();

        $totalItems = $reports->total();
        $currentPage = $reports->currentPage();
        $perPage = 30;


        return view('reports.show', compact('sickness', 'programs', 'months', 'reports', 'statistics', 'centers', 'instructors', 'years', 'lessons', 'totalItems', 'currentPage', 'perPage'));
    }


    /**
     * @throws \Exception
     */


    public function statistics($filter = null)
    {

        if (!$filter) {
            $reports = Reports::distinct('members_id')->get();
        } else {
            $reports = Reports::filter($filter)->distinct('members_id')->get();
        }


        $uniqueReports = $reports->unique('members_id');

        $statistics = [
            'membersAll' => $uniqueReports->count(),
            'payLessons' => (int)$uniqueReports->sum('pay_lessons'),
            'freeLessons' => (int)$uniqueReports->sum('free_lessons'),
            'allLessons' => (int)$uniqueReports->sum('free_lessons') + (int)$uniqueReports->sum('pay_lessons'),
            'members318' => 0,
            'members318pay' => 0,
            'members318free' => 0,
            'members1955' => 0,
            'members1955pay' => 0,
            'members1955free' => 0,
            'members55' => 0,
            'members55pay' => 0,
            'members55free' => 0,
            'membersNo' => 0,
            'membersNopay' => 0,
            'membersNofree' => 0,
        ];

        foreach ($uniqueReports as $report) {
            $birthday = new DateTime($report->member->birthday);
            $interval = $birthday->diff(new DateTime);


            if ($interval->y >= 3 && $interval->y <= 18) {
                $statistics['members318'] += 1;

            } elseif ($interval->y >= 19 && $interval->y <= 55) {
                $statistics['members1955'] += 1;
            } elseif ($interval->y > 55) {
                $statistics['members55'] += 1;
            } elseif ($interval->y <= 0 && $interval->y <= 2) {
                $statistics['membersNo'] += 1;
            }


        }
        foreach ($uniqueReports as $report) {
            $birthday = new DateTime($report->member->birthday);
            $interval = $birthday->diff(new DateTime);


            if ($interval->y >= 3 && $interval->y <= 18) {

                $statistics['members318pay'] += (int)$report->pay_lessons;
                $statistics['members318free'] += (int)$report->free_lessons;
            } elseif ($interval->y >= 19 && $interval->y <= 55) {

                $statistics['members1955pay'] += (int)$report->pay_lessons;
                $statistics['members1955free'] += (int)$report->free_lessons;
            } elseif ($interval->y > 55) {

                $statistics['members55pay'] += (int)$report->pay_lessons;
                $statistics['members55free'] += (int)$report->free_lessons;
            } elseif ($interval->y <= 0 && $interval->y <= 2) {

                $statistics['membersNopay'] += (int)$report->pay_lessons;
                $statistics['membersNofree'] += (int)$report->free_lessons;
            }


        }


        return $statistics;

    }

    public function add(Request $request)
    {
        $currentCenters = [];

        foreach (User::find(Auth::id())->centers as $center) {
            $currentCenters[] = $center->id;
        }

        if (!in_array(3, $currentCenters)) {
            $centers = Centers::query();
            $centers->whereIn('id', $currentCenters);
            $centers = $centers->get();

            $instructors = Instructors::query();
            $instructors->whereIn('centers_id', $currentCenters);
            $instructors = $instructors->get();

            $members = Members::query();
            $members->whereIn('centers_id', $currentCenters);
            $members = $members->get();
        } else {
            $centers = Centers::all();
            $instructors = Instructors::all();
            $members = Members::all();
        }


        return view('reports.add', compact('centers', 'instructors', 'members'));
    }

    public function store(ReportsStoreRequest $request)
    {
        $data = $request->validated();

        Reports::create($data);
        return redirect(route('reports'));
    }


    public function update(ReportsUpdateRequest $request, Reports $report)
    {


        $data = $request->validated();


        $report->update($data);

        return redirect(route('reports'));
    }

    public function delete(Request $request, Reports $report)
    {

        $forDelete = Reports::find($report->id);
        if (!$forDelete->delete()) {
            throw new \Exception('Невозможно удалить запись');
        } else {
            return redirect(route('reports'));
        }

    }

    public function edit(Reports $report)
    {
        $currentCenters = [];

        foreach (User::find(Auth::id())->centers as $center) {
            $currentCenters[] = $center->id;
        }

        if (!in_array(3, $currentCenters)) {
            $centers = Centers::query();
            $centers->whereIn('id', $currentCenters);
            $centers = $centers->get();

            $instructors = Instructors::query();
            $instructors->whereIn('centers_id', $currentCenters);
            $instructors = $instructors->get();

            $members = Members::query();
            $members->whereIn('centers_id', $currentCenters);
            $members = $members->get();
        } else {
            $centers = Centers::all();
            $instructors = Instructors::all();
            $members = Members::all();
        }


        return view('reports.edit', compact('centers', 'report', 'instructors', 'members'));

    }

    public function excel(FilterRequest $request)
    {

        $currentCenters = [];

        foreach (User::find(Auth::id())->centers as $center) {
            $currentCenters[] = $center->id;
        }

        $data = $request->validated();


        if (!in_array(3, $currentCenters)) {
            $instructors = Instructors::query();
            $instructors->whereIn('centers_id', $currentCenters);
            $instructors = $instructors->get();
        } else {
            $instructors = Instructors::all();
        }

        if (!in_array(3, $currentCenters)) {
            $centers = Centers::where('user_id', Auth::id())->get();
        } else {
            $centers = Centers::all();
        }


        if (isset($data['filters'])) {


            if (!isset($data['filters']['centers_id'])) {
                $data['filters']['centers_id'] = $centers->pluck('id')->toArray();
            }


            $filter = app()->make(ReportsFilter::class, ['queryParams' => array_filter($data['filters'])]);


            if (isset($data['filters']['diagnosis'])) {
                $diagnosisFilter = $data['filters']['diagnosis'];
                $tempReports = Reports::filter($filter);
                $reports = $tempReports->whereHas('member', function ($tempReports) use ($diagnosisFilter) {
                    $count = 0;
                    foreach ($diagnosisFilter as $val) {
                        if ($count > 0) {
                            $tempReports->orWhere('diagnosis', trim($val));
                        } else {
                            $tempReports->where('diagnosis', trim($val));
                        }
                        $count++;
                    }

                })->get();
            } else {
                $reports = Reports::filter($filter)->get();
            }

            unset($data['filters']['diagnosis']);

        } else {
            if (!in_array(3, $currentCenters)) {

                if (!isset($data['filters']['centers_id'])) {
                    $filterCenter['centers_id'] = $centers->pluck('id')->toArray();
                }

                $filter = app()->make(ReportsFilter::class, ['queryParams' => array_filter($filterCenter)]);
                $reports = Reports::filter($filter)->get();
            } else {
                $reports = Reports::all();

            }


        }


        $fileName = uniqid() .'123'. '.xlsx';
        (new FastExcel($reports))->export($fileName);

        return DIRECTORY_SEPARATOR . $fileName;
    }

    private function statisticsByFilter($reports, $currentCenters)
    {


        $statistics = [
            'membersAll' => $reports->pluck('members_id')->unique()->count(),
            'payLessons' => $reports->pluck('pay_lessons')->sum(),
            'freeLessons' => $reports->pluck('free_lessons')->sum(),
            'allLessons' => $reports->pluck('pay_lessons')->sum() + $reports->pluck('free_lessons')->sum(),
            'members318' => 0,
            'members318pay' => 0,
            'members318free' => 0,
            'members1955' => 0,
            'members1955pay' => 0,
            'members1955free' => 0,
            'members55' => 0,
            'members55pay' => 0,
            'members55free' => 0,
            'membersNo' => 0,
            'membersNopay' => 0,
            'membersNofree' => 0,
        ];

        foreach ($reports->unique('members_id') as $report) {
            $birthday = new DateTime($report->member->birthday);
            $interval = $birthday->diff(new DateTime);


            if ($interval->y >= 3 && $interval->y <= 18) {
                $statistics['members318'] += 1;

            } elseif ($interval->y >= 19 && $interval->y <= 55) {
                $statistics['members1955'] += 1;
            } elseif ($interval->y > 55) {
                $statistics['members55'] += 1;
            } elseif ($interval->y <= 0 && $interval->y <= 2) {
                $statistics['membersNo'] += 1;
            }


        }
        foreach ($reports->unique('members_id') as $report) {
            $birthday = new DateTime($report->member->birthday);
            $interval = $birthday->diff(new DateTime);


            if ($interval->y >= 3 && $interval->y <= 18) {

                $statistics['members318pay'] += (int)$report->pay_lessons;
                $statistics['members318free'] += (int)$report->free_lessons;
            } elseif ($interval->y >= 19 && $interval->y <= 55) {

                $statistics['members1955pay'] += (int)$report->pay_lessons;
                $statistics['members1955free'] += (int)$report->free_lessons;
            } elseif ($interval->y > 55) {

                $statistics['members55pay'] += (int)$report->pay_lessons;
                $statistics['members55free'] += (int)$report->free_lessons;
            } elseif ($interval->y <= 0 && $interval->y <= 2) {

                $statistics['membersNopay'] += (int)$report->pay_lessons;
                $statistics['membersNofree'] += (int)$report->free_lessons;
            }


        }


        return $statistics;

    }
}
